package lg.minecraft.plugin.pokemonmenu.listener;

import com.cobblemon.mod.common.api.storage.party.PlayerPartyStore;
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
import com.cobblemon.mod.common.pokemon.Pokemon;
import com.cobblemon.mod.common.util.PlayerExtensionsKt;
import lg.minecraft.plugin.cobblemoncore.util.BukkitNmsConverter;
import lg.minecraft.plugin.cobblemoncore.util.CobblemonType;
import lg.minecraft.plugin.pokemonmenu.LGPokemonMenu;
import lg.minecraft.plugin.pokemonmenu.PokemonPlayer;
import lg.minecraft.plugin.pokemonmenu.event.EventFactory;
import lg.minecraft.plugin.pokemonmenu.event.ItemToPokemonEvent;
import lg.minecraft.plugin.pokemonmenu.event.PlayerEndBattleHealEvent;
import lg.minecraft.plugin.pokemonmenu.gui.EditInventor;
import lg.minecraft.plugin.pokemonmenu.gui.ItemToPokemonInventory;
import lg.minecraft.plugin.pokemonmenu.gui.PokemonInventory;
import lg.minecraft.plugin.pokemonmenu.gui.ViewPartyInventor;
import lg.minecraft.plugin.pokemonmenu.manager.PokemonPlayerManger;
import lg.minecraft.plugin.pokemonmenu.util.PokemonNBTUtil;
import net.minecraft.class_3222;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;

import java.util.UUID;

/**
 * @author langle__
 * @version 1.0
 */
public class PlayerEvent implements Listener {

    @EventHandler(priority = EventPriority.MONITOR)
    public void onPlayerEndBattleHeal(PlayerEndBattleHealEvent event) {
        if (event.isCancelled()) return;
        Player player = event.getPlayer();

        class_3222 nmsPlayer = BukkitNmsConverter.toPlayer(player);
        PlayerPartyStore party = PlayerExtensionsKt.party(nmsPlayer);

        if (!LGPokemonMenu.canPartyBeHealed(party)) return;

        party.heal();
        player.sendMessage(LGPokemonMenu.getMessage().getHealPokemon());
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();

        PokemonPlayerManger manger = PokemonPlayerManger.INSTANCE;
        if (manger.containsPokemonPlayer(uuid)) {
            manger.removePokemonPlayer(uuid);
        }

        manger.addPokemonPlayer(uuid, new PokemonPlayer(player));
    }

    @EventHandler(priority = EventPriority.MONITOR)
    public void onPlayerQuit(PlayerQuitEvent event) {
        Player player = event.getPlayer();

        PokemonPlayerManger.INSTANCE.removePokemonPlayer(player.getUniqueId());
    }

    @EventHandler
    public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
        if (event.isCancelled()) return;
        Player player = event.getPlayer();
        Entity target = event.getRightClicked();
        EquipmentSlot hand = event.getHand();
        PokemonPlayerManger pokemonPlayerManger = PokemonPlayerManger.INSTANCE;
        PokemonPlayer pokemonPlayer = pokemonPlayerManger.getPokemonPlayer(player);

        if (!player.isSneaking() || hand != EquipmentSlot.HAND) return;

        EntityType entityType = target.getType();
        if (entityType == CobblemonType.COBBLEMON_POKEMON_TYPE && pokemonPlayer.isEditMode() && player.hasPermission("LGPokemonMenu.edit")) {
            PokemonEntity entity = BukkitNmsConverter.toPokemonEntity(target);
            Pokemon pokemon = entity.getPokemon();
            pokemonPlayer.setPreviousInventory(null);
            new EditInventor(pokemon).openInventory(player);
        } else if (entityType == CobblemonType.COBBLEMON_POKEMON_TYPE && pokemonPlayer.isOpenWildPokemon()) {
            PokemonEntity entity = BukkitNmsConverter.toPokemonEntity(target);
            Pokemon pokemon = entity.getPokemon();
            if (pokemon.isPlayerOwned()) {
                class_3222 owner = pokemon.getOwnerPlayer();
                if (owner != null) {
                    UUID ownerUUID = owner.method_5667();
                    if (player.getUniqueId() == ownerUUID) {
                        event.setCancelled(true);
                    } else {
                        if (pokemonPlayerManger.getPokemonPlayer(ownerUUID).isDisabledView() && !player.hasPermission("LGPokemonMenu.bypass.disabled_view")) {
                            return;
                        }
                    }
                }
            }
            pokemonPlayer.setPreviousInventory(null);
            new PokemonInventory(pokemon).openInventory(player);
        } else if (entityType == EntityType.PLAYER && pokemonPlayer.isViewPlayerParty()) {
            Player targetPlayer = (Player) target;
            PokemonPlayer targetPokemonPlayer = pokemonPlayerManger.getPokemonPlayer(targetPlayer);
            if (targetPokemonPlayer.isDisabledView() && !player.hasPermission("LGPokemonMenu.bypass.disabled_view")) return;
            Pokemon[] pokemonArray = new Pokemon[6];
            for (int i = 0; i < 6; i++) {
                pokemonArray[i] = targetPokemonPlayer.getPartyPokemon(i);
            }

            new ViewPartyInventor(pokemonArray).openInventory(player);
        }
    }

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        Player player = event.getPlayer();
        EquipmentSlot hand = event.getHand();
        Action action = event.getAction();
        PlayerInventory inventory = player.getInventory();
        ItemStack bukkitItem = inventory.getItemInMainHand();

        if (hand != EquipmentSlot.HAND || (action != Action.RIGHT_CLICK_AIR && action != Action.RIGHT_CLICK_BLOCK) || bukkitItem.getType() != CobblemonType.COBBLEMON_POKEMON_MODEL_TYPE) return;

        PokemonNBTUtil.Entry entry = PokemonNBTUtil.extractPokemonFromNBT(bukkitItem, BukkitNmsConverter.getRegistryAccess());

        if (entry.getPokemon() == null) return;

        if (LGPokemonMenu.getMainConfig().getToPokemon() > 0 && LGPokemonMenu.getEconomy() != null) {
            new ItemToPokemonInventory(entry, bukkitItem).openInventory(player);
            inventory.setItemInMainHand(null);
            event.setCancelled(true);
            return;
        }

        ItemToPokemonEvent itemToPokemonEvent = EventFactory.callItemToPokemonEvent(player, entry.getPokemon());
        if (itemToPokemonEvent.isRemoveItem()) inventory.setItemInMainHand(null);
        if (itemToPokemonEvent.isCancelled()) return;

        entry.run();
        PokemonPlayer pokemonPlayer = PokemonPlayerManger.INSTANCE.getPokemonPlayer(player);
        pokemonPlayer.addPartyPokemon(entry.getPokemon());
        inventory.setItemInMainHand(null);
        event.setCancelled(true);
        player.sendMessage(LGPokemonMenu.getMessage().getModelToPokemon());
    }

}
